
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width , initial-scale=1.0 , user-scalable=0 , minimum-scale=1.0 , maximum-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>BuildSystem | Studio</title>
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="pingback" href="http://www.wy182000.com/wordpress/xmlrpc.php" />
<link rel="alternate" type="application/rss+xml" title="Studio &raquo; Feed" href="http://www.wy182000.com/feed/" />
<link rel="alternate" type="application/rss+xml" title="Studio &raquo; 评论Feed" href="http://www.wy182000.com/comments/feed/" />
<link rel='stylesheet' id='wp-downloadmanager-css'  href='http://www.wy182000.com/wordpress/wp-content/plugins/wp-downloadmanager/download-css.css?ver=1.63' type='text/css' media='all' />
<script type='text/javascript' src='http://www.wy182000.com/wordpress/wp-includes/js/jquery/jquery.js?ver=1.11.0'></script>
<script type='text/javascript' src='http://www.wy182000.com/wordpress/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script>
<link rel='prev' title='Linux 设置 多ip，多vlan' href='http://www.wy182000.com/2011/08/16/linux-%e8%ae%be%e7%bd%ae-%e5%a4%9aip%ef%bc%8c%e5%a4%9avlan/' />
<link rel='next' title='gcc详解' href='http://www.wy182000.com/2011/09/09/gcc%e8%af%a6%e8%a7%a3/' />
<link rel='canonical' href='http://www.wy182000.com/2011/09/01/buildsystem/' />
<style type="text/css" id="custom-background-css">
body.custom-background { background-color: #cce5cf; }
</style>
<script type="text/javascript">(function(){mod_txt = '#'; adminBar = "" || 0})();</script>
<script type="text/javascript" src="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/frontopen.js?ver=1.4.03.30"></script>
<script type="text/javascript" src="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/include/lightbox-2.6.min.js"></script>
<link href="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/lightbox.css" rel="stylesheet" type="text/css" />

<link rel="stylesheet" type="text/css" media="all" href="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/style.css?ver=1.4.03.30" />
<link rel="stylesheet" type="text/css" media="all" href="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/mobile.css?ver=1.4.03.30" />
<style type="text/css">@media screen and (min-width:1366px){.c-con{height:140px;}}
</style>

<!--[if lt IE 9]><script src="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/html5.js"></script><![endif]-->
<link rel="stylesheet" href="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/css/font-awesome.min.css?ver=1.4.03.30">
<!--[if IE 7]>
<link rel="stylesheet" href="http://www.wy182000.com/wordpress/wp-content/themes/frontopen2_v1.4.03.30/css/font-awesome-ie7.min.css?ver=1.4.03.30">
<![endif]-->
</head>

<body class="single single-post postid-691 single-format-standard custom-background">
<div class="loading"></div>
<div class="web_bod">
<header class="header marauto">
    <span class="logo">
        <a href="http://www.wy182000.com/" title="Studio" rel="home"><img src="http://www.wy182000.com/wordpress/wp-content/uploads/2014/09/studio.png" alt="Studio" /></a>
        <i>wy182000@126.com</i>
    </span>
    <form role="search" method="get" id="searchform" action="http://www.wy182000.com/">
      <span class="search">
        <input name="s" id="s" type="text"  class="input" value="" onclick="this.value = '';" style="color:#999" onkeypress="javascript:if(event.keyCode == 13){query(this.value);}" x-webkit-speech=""/>
        <button id="searchsubmit" class="btn">SEARCH</button>
      </span>
    </form>
    <div class="cls"></div>
</header>
<div class="nav marauto">
    <div class="tig">
          <div class="gonggao">
        <ul id="g_box">
            <li><span class="gg_tx"><i class="icon-volume-off icon-large"></i> 网站改版了</span></li>        </ul>
      </div>
    </div>
<div class="navlist">
<div class="cls"></div>
</div>
</div>


<nav class="navcon marauto">
  <div id="mobile_nav_btn">网站导航</div>
  <div class="menu-header"><ul id="menu-menu" class="menu"><li id="menu-item-328" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-328"><a href="http://www.wy182000.com">首页</a></li>
<li id="menu-item-331" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-331"><a target="_blank" href="http://www.wy182000.com/wordpress/wp-admin/post-new.php">发表文章</a></li>
<li id="menu-item-2026" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-2026"><a target="_blank" href="http://www.wy182000.com/message/">留言板</a></li>
</ul></div>  
  </nav>   
  <section class="conter marauto"><script type="text/javascript">loading('33%',1000)</script>
  <div id="container">
      <div id="content" role="main" style="width:96%">
      <div class="mbx"><i class="icon-home icon-large" style="font-size:14px;"></i>
<a href="http://www.wy182000.com"  class="gray">首页</a>  >  <a href="http://www.wy182000.com/category/computer/" title="查看Computer中的全部文章">Computer</a>  >  <a href="http://www.wy182000.com/category/computer/build/" title="查看build中的全部文章">build</a>  >  BuildSystem</div>

				<div id="post-691" class="post-691 post type-post status-publish format-standard hentry category-build category-computer tag-gyp tag-scons">
                <div class="c-top2" id="post-55">
                <div class="datetime">2011<br />09-01</div>
					<header class="tit"><h1 class="entry-title">BuildSystem</h1>
					<aside class="entry-meta iititle2">
                        <span><i class="icon-user icon-large"></i> <a href="http://www.wy182000.com/author/wy182000/" title="由wy182000发布" rel="author">wy182000</a></span><span><i class="icon-folder-open icon-large"></i> <a href="http://www.wy182000.com/category/computer/build/" title="查看build中的全部文章" rel="category tag">build</a>, <a href="http://www.wy182000.com/category/computer/" title="查看Computer中的全部文章" rel="category tag">Computer</a></span><span><i class="icon-eye-open icon-large"></i> 围观<i id="number">431</i><script type="text/javascript">jQuery(function($){$.get("http://www.wy182000.com/fo_ajax?ajax=getPostViews&postID=691",function(data){if(data.length < 10)$('#number').text(data)});})</script>次</span><span><i class="icon-comment-alt icon-large"></i> <a href="http://www.wy182000.com/2011/09/01/buildsystem/#respond" title="《BuildSystem》上的评论">留下评论</a></span><span><i class="icon-pencil icon-large"></i> 编辑日期：<time>2011-09-01</time></span><span><i class="icon-zoom-in icon-large"></i> 字体：<a href="javascript:;" onclick="checkFontSize(18)">大</a> <a href="javascript:;" onclick="checkFontSize(16)">中</a> <a href="javascript:;" onclick="checkFontSize(14)">小</a></span>					</aside>
                    </header>
                    <div class="cls"></div>
		    </div>
                    <!-- .entry-meta -->

					<article class="entry-content">
                    
						<div style="line-height: 1.5" id="table-of-contents">
<h2 style="line-height: 1.5; margin-top: 10px; clear: none"><font face="Verdana"><font style="font-size: 11pt" color="#333333"><font style="font-weight: bold">Table of Contents</font></font></font></h2>
<div id="text-table-of-contents">
<ul style="list-style-type: disc; margin-left: 45px">
<li><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1 BuildSystem </font></font></font></a>
<ul style="list-style-type: circle; margin-left: 45px">
<li style="list-style-type: disc"><font style="text-decoration: none"><font style="font-size: 10pt"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1"><font color="#0066ff" face="Verdana">1.1 GYP </font></a></font></font>
<ul style="margin-left: 45px">
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_1"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.1 设计目标 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.2 构建文件 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_3"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.3 .gyp文件剖析 </font></font></font></a>
<ul style="margin-left: 45px">
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_3_1"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.3.1 conditions </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_3_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.3.2 targets </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_3_3"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.3.3 includes </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_3_4"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.3.4 actions </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_3_5"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.3.5 variables </font></font></font></a></li>
</ul>
</li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_4"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.4 early and late phases </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_5"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.5 operator </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_6"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.6 路径内容属性 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_1_7"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.1.7 总结 </font></font></font></a></li>
</ul>
</li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2 Scons </font></font></font></a>
<ul style="margin-left: 45px">
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_1"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.1 Make缺陷 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.2 构建文件 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3 SConstruct文件剖析 </font></font></font></a>
<ul style="margin-left: 45px">
<li style="list-style-type: disc"><font style="text-decoration: none"><font style="font-size: 10pt"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_1"><font color="#0066ff" face="Verdana">1.2.3.1 Builder </font></a></font></font>
<ul style="margin-left: 45px">
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_1_1"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.1.1 编译参数和自动分析编译依赖 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_1_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.1.2 源文件使用不同参数编译 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_1_3"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.1.3 库链接 </font></font></font></a></li>
</ul>
</li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.2 Dependencies </font></font></font></a>
<ul style="margin-left: 45px">
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_2_1"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.2.1 分析依赖 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_2_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.2.2 判断依赖变化 </font></font></font></a></li>
</ul>
</li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_3"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.3 Environment </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_3_4"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.3.4 Hierarchical Builds </font></font></font></a></li>
</ul>
</li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_4"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.4 其他问题 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_2_5"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.2.5 总结 </font></font></font></a></li>
</ul>
</li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_3"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.3 Ninja </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_4"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.4 ABS </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5 CMake </font></font></font></a>
<ul style="margin-left: 45px">
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_1"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.1 构建文件 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_2"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.2 CMakeLists.txt解析 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_3"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.3 变量和属性 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_4"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.4 注释 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_5"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.5 编译类型 </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_6"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.6 生成config.h </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_7"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.7 Makefile </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_5_8"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.5.8 总结 </font></font></font></a></li>
</ul>
</li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_6"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.6 Others </font></font></font></a></li>
<li style="list-style-type: disc"><a href="http://www.cnblogs.com/dirlt/archive/2011/05/29/#sec-1_7"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">1.7 个人感觉 </font></font></font></a></li>
</ul>
</li>
</ul>
</div>
</div>
<div style="line-height: 1.5" id="outline-container-1" class="outline-2">
<h2 style="line-height: 1.5; margin-top: 10px; clear: none" id="sec-1"><font face="Verdana"><font color="#333333"><span class="section-number-2"><font style="font-size: 11pt"><font style="font-weight: bold">1</font></font></span><font style="font-size: 11pt"><font style="font-weight: bold"> BuildSystem </font></font></font></font></h2>
<div id="text-1" class="outline-text-2">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">words from huangjun@baidu.com(leemars528)</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">内部构建系统*必须*要求所有模块都使用这个构建系统。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">模块的依赖*不应该*通过额外的系统来管理。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">*应该*能够指定足够细致的粒度。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">就*应该*只依赖于需要生成接口所需要的最少内容。</font></font></li>
</ul>
</div>
<div id="outline-container-1_1" class="outline-3">
<h3 style="border-bottom-style: dotted; border-bottom-color: #d6d6d6; line-height: 1.5; clear: none" id="sec-1_1"><font face="Verdana"><span class="section-number-3"><font style="font-size: 10pt"><font style="font-weight: bold">1.1</font></font></span><font style="font-size: 10pt"><font style="font-weight: bold"> GYP </font></font></font></h3>
<div id="text-1_1" class="outline-text-3">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">gyp(generate your project)是chromium的构建系统，地址在</font></font><font style="font-size: 10pt"><a href="http://code.google.com/p/gyp/"><font color="#0066ff"><font style="text-decoration: none" face="Verdana">http://code.google.com/p/gyp/</font></font></a></font><font face="Verdana"><font style="font-size: 10pt">。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">关于GYP和CMake的对比在</font></font><font style="font-size: 10pt"><a href="http://code.google.com/p/gyp/wiki/GypVsCMake"><font color="#0066ff"><font style="text-decoration: none" face="Verdana">http://code.google.com/p/gyp/wiki/GypVsCMake</font></font></a></font><font face="Verdana"><font style="font-size: 10pt">。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">文档建设还是比较差的，并且个人使用一个很简单的例子都没有work成功。虽然wiki有UserDocumentation但是里面介绍非常粗略，基本上可以认为是一个没有成熟产品。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">虽然没有比较好的使用文档，主页wiki里面还有有一些关于gyp本身比较好的描述，以及设计的初衷。 通过学习这些内容，可以对构建系统有更加深入的认识。感谢huangjun@baidu.com(leemars528)给我的建议， 他透露这个可能是gg内部的一个构建系统原型。并且之前yangliu@baidu.com(from google)给我举构建系统例子的时候， 表达方式上和gyp也非常相似，所以有理由相信gyp很像现在google内部的构建系统。</font></font></p>
</div>
<div id="outline-container-1_1_1" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_1_1"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.1.1</font></span><font style="font-weight: bold"> 设计目标 </font></font></font></h4>
<div id="text-1_1_1" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">gyp设计针对目标就是为了解决chromium浏览器构建问题，最重要的就是支持多平台的构建。因此生成的后端可能是Scons/Make(Unix/Linux)，Xcode(Mac)或者是Visual Studio(Windows).并且因为chromium内部都是C/C++文件， 因此主要考虑方便C/C++程序的构建。设计时候还考虑到下面这些问题：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">debug vs. release.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">cross compile.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">toolchain interface.</font></font></li>
</ul>
</div>
</div>
<div id="outline-container-1_1_2" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_1_2"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.1.2</font></span><font style="font-weight: bold"> 构建文件 </font></font></font></h4>
<div id="text-1_1_2" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">构建文件名字不固定，但是后缀通常是.gyp和.gypi(gyp included).构建文件内容就是python的一个数据结构(可以认为是json,不过允许#作为注释并且允许trailing的).这样做的一个方便结果就是为了读取构建文件信息， 只需要eval一下文件的内容即可，就可以得到这个构建文件的描述了。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">下面是一个example：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">{
    'target_defaults':{
        'defines':['DEBUG'],       
    },
    'targets':[
        {
            'target_name':'test', #生成的文件.
            'type':'executable', #可执行程序.
            'sources':['test.cc'],
            'defines':['FOO']
        }
    ]    
}
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">在后面部分会详细解释构建文件里面的每个element。</font></font></p>
</div>
</div>
<div id="outline-container-1_1_3" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_1_3"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.1.3</font></span><font style="font-weight: bold"> .gyp文件剖析 </font></font></font></h4>
<div id="text-1_1_3" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">整个构建文件最顶层是一个字典，包含了下面这些key：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">conditions //条件判断</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">includes //包含的构建文件</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">target<sub style="position: static; line-height: 1.5; height: auto; top: auto">defaults</sub> //构建目标默认属性</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">targets //构建目标列表</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">variables //构建文件使用的变量</font></font></li>
</ul>
</div>
<div id="outline-container-1_1_3_1" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_1_3_1"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.1.3.1</font></span><font style="font-weight: bold"> conditions </font></font></font></h5>
<div id="text-1_1_3_1" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">conditions分为两种行为。普通的conditions就在load构建文件之后立即计算，另外一种是target<sub style="position: static; line-height: 1.5; height: auto; top: auto">conditions</sub>是在计算完成依赖之后然后来进行计算的，两个过程分别就是early and late phases阶段。对于conditions写法非常简单：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">'conditions':[
    ['OS==Linux',{'sources':['linux_interface.cc']}]
]
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">对于condition的判断，主要还是为了能够修改一些描述属性。从文档上来看的话，默认提供的条件就是OS判断，其他判断应该都是变量的判断。</font></font></p>
</div>
</div>
<div id="outline-container-1_1_3_2" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_1_3_2"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.1.3.2</font></span><font style="font-weight: bold"> targets </font></font></font></h5>
<div id="text-1_1_3_2" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">target部分的话会对target<sub style="position: static; line-height: 1.5; height: auto; top: auto">defaults里面设定的内容默认进行merge。比如上面例子的话，对于target</sub>/test来说， 使用的defines就会是-DDEBUG -DFOO。当然对于这种东西是可以进行其他策略选择的，比如如果修改成下面格式，那么就是直接替换：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">'defines=':['FOO']
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">生成的defines就是-DFOO了。或者是可以剔除掉：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">'defines!':['DEBUG']

</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">生成的defines就没有任何内容了。通过在选项key后面添加操作符号来达到自定义目的(相对于全局环境).</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">对于一个target包括了下面这些重要属性：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">actions(list) //执行命令</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">all<sub style="position: static; line-height: 1.5; height: auto; top: auto">dependent</sub><sub style="position: static; line-height: 1.5; height: auto; top: auto">settings</sub>(dict) //如果依赖这个target的话，需要使用的设置</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">configurations(dict) //配置</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">defines(list) //对于C/C++的defines</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">dependencies(list) //依赖对象。如果是本文件的话那么直接引用，如果是其他文件的话，使用path/xxx.gyp:target.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">direct<sub style="position: static; line-height: 1.5; height: auto; top: auto">dependent</sub><sub style="position: static; line-height: 1.5; height: auto; top: auto">settings</sub>(dict) //直接依赖这个taregt的话，需要使用的设置</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">include<sub style="position: static; line-height: 1.5; height: auto; top: auto">dirs</sub>(list) //头文件目录</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">libraries(list) //目标需要链接的库</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">link<sub style="position: static; line-height: 1.5; height: auto; top: auto">settings</sub>(dict) //依赖这个target，需要使用的链接参数</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">sources(list) //源文件</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">target<sub style="position: static; line-height: 1.5; height: auto; top: auto">conditions</sub>(list) //和conditions类似，但是是在完全计算之后然后来判断</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">target<sub style="position: static; line-height: 1.5; height: auto; top: auto">name</sub>(string) //名字</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">type //目标类型，现在只是支持static<sub style="position: static; line-height: 1.5; height: auto; top: auto">library</sub>,shared<sub style="position: static; line-height: 1.5; height: auto; top: auto">library</sub>,executable和none</font></font></li>
</ul>
</div>
</div>
<div id="outline-container-1_1_3_3" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_1_3_3"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.1.3.3</font></span><font style="font-weight: bold"> includes </font></font></font></h5>
<div id="text-1_1_3_3" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">gyp倾向的组织就是在toplevel上面存在一个gyp文件，可以存在子目录下面，但是子目录下面并不存放一个完整的构建文件， 通常只是存放构建文件的片段。为了区分，后缀为gypi。本身来说，这个gypi并不可以直接被gyp所接受生成native构建系统文件， 唯一的作用就是被toplevel的gyp文件进行include。如果对于Linux系统来说，最终生成的Makefile应该是一份大Makefile并且没有递归make的操作。 关于构造一个没有递归的Makefile是非常有价值的，不管是对于调试还是提升编译速度方面。可以参考文章Recusive Make Considered Harmful.</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">一旦我们允许include子目录的gypi文件进来，我们就必须规定哪些字段应该是文件。原因是假设存在src目录下面有src/BUILD.gypi这样一个文件，sources内容如下:</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">'sources':['src.cc']
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">而在上层BUILD.gyp文件里面，使用includes语法：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">'includes':['./src/BUILD.gypi']
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">那么在生成大Makefile的时候，我们必须清楚'sources'字段里面内容都是文件，不应该直接使用src.cc， 相反应该加上目录前缀src，</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">最终应该使用src/src.cc这样一个文件。关于哪些字段里面内容是路径， 这个在gyp里面有详细规定，在后面小节里面我们也会提到。</font></font></p>
</div>
</div>
<div id="outline-container-1_1_3_4" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_1_3_4"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.1.3.4</font></span><font style="font-weight: bold"> actions </font></font></font></h5>
<div id="text-1_1_3_4" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">actions是targets里面的一个特殊属性，主要是用来进行target的自定义操作的。关于rule的部分， 应该问问huangjun@baidu.com,因为他实际操作过gyp并且阅读过Chrmoium里面的.gyp文件。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">每个action是一个dict，主要包含4个属性：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">action<sub style="position: static; line-height: 1.5; height: auto; top: auto">name</sub>(string). //操作名称</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">input(list) //输入文件</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">outputs(list) //输出文件</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">actions(list) //命令</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">有了这些属性就可以做一个完整的操作抽象。</font></font></p>
</div>
</div>
<div id="outline-container-1_1_3_5" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_1_3_5"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.1.3.5</font></span><font style="font-weight: bold"> variables </font></font></font></h5>
<div id="text-1_1_3_5" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">variables这个小节里面是进行变量的定义，格式是dict。下面是一个例子：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">'variables':{
    'common_files':['src/common.cc','src/interface.cc'],
}
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">为了引用变量，我们可以这样编写：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">&lt;(common_files)
&lt;@(common_files)
&gt;(common_files)
&gt;@(common_files)
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">总之引用变量必须加上(),同时在前面加上&lt;,&lt;@,&gt;,&gt;@的4种中一种前缀符号。关于前缀符号的含义， 会在后面的operator小节里面说明。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">对于变量类型，一共分为3类：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">predefined variables //预定义变量</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">user-defined variables //用户定义变量</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">automatic variables //自动变量</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">预定义变量比如OS(系统环境),EXECUTABLE<sub style="position: static; line-height: 1.5; height: auto; top: auto">SUFFIX</sub>(可执行文件后缀).用户自定义变量就不再赘述。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">自动变量类似于Makefile里面的$@,$<sup style="position: static; line-height: 1.5; bottom: auto; height: auto">这样的变量，好比反射。比如在target</sup><sub style="position: static; line-height: 1.5; height: auto; top: auto">conditions部分的话，</sub>我们根据不同类型程序来做不同的condition：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">'target_conditions':[
['_type=='static_library',{'sources':['func.cc']}]
]
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">这样对于target为static<sub style="position: static; line-height: 1.5; height: auto; top: auto">library都会联编func</sub>.cc这个文件了，自动变量是就是属性名称之前加上</font><sub style="position: static; line-height: 1.5; height: auto; top: auto"><font style="font-size: 10pt">构成的。</font></sub></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">存在自动变量非常必要。有时候我们在全局环境中，希望根据不同的条件来定义不同的行为，并且是在计算的同时在来做条件判断的。 这样就提出一个要求就是，条件判断部分必须有能力知道，当前到底在计算什么东西(反射)。</font></font></p>
</div>
</div>
</div>
<div id="outline-container-1_1_4" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_1_4"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.1.4</font></span><font style="font-weight: bold"> early and late phases </font></font></font></h4>
<div id="text-1_1_4" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">对于变量展开和条件判断有两个不同的阶段：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">载入文件之后进行，就是early phase。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">计算完成之后进行，就是late phase。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">对于两个阶段允许不同操作是非常必要的。对于early phase这个肯定需要，而对于late phase的话， 有时候我们是希望了解到gyp处理完成某个target之后所有信息，然后进行判断的。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">ps:comake2在设计的时候，就没有考虑late phase这个功能。造成没有办法在应用层添加延迟计算这样一个特性。 最终只能够是修改comake2代码来完成需求。</font></font></p>
</div>
</div>
<div id="outline-container-1_1_5" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_1_5"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.1.5</font></span><font style="font-weight: bold"> operator </font></font></font></h4>
<div id="text-1_1_5" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">关于每个操作符号的含义：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">x= //字段内容进行覆盖</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">x? //如果字段没有定义，那么就进行覆盖</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">x+ //字段内容进行merge</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">&lt; (x) //early phase计算变量x，并且以string类型返回结果</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">&gt; (x) //late phase计算变量x，并且以string类型返回结果</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">&lt; @(x) //early phase计算变量x，并且以list类型返回结果</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">&gt; @(x) //late phase计算变量x，并且以list类型返回结果</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">x! //从已有的x字段中排除部分</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">x/ //操作允许使用include/exclude，内容是一个正则表达式来进行包含和排除列表里面内容</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">&lt; !(x) //认为x是一个shell command，得到执行结果作为string类型返回</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">&lt; !@(x) //认为x是一个shell command，得到执行结果作为list类型返回</font></font></li>
</ul>
</div>
</div>
<div id="outline-container-1_1_6" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_1_6"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.1.6</font></span><font style="font-weight: bold"> 路径内容属性 </font></font></font></h4>
<div id="text-1_1_6" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">在includes这个小节提到了，gyp规定了某些属性的内容必须为路径。这些属性是：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">files.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">include<sub style="position: static; line-height: 1.5; height: auto; top: auto">dirs</sub>.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">inputs.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">libraries.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">outputs.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">sources.</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">但是gyp对于里面的内容也做了一些特殊处理。对于内容来说，如果以下面这些字符开头：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">/ //绝对路径</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">$ //变量</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">- //链接参数比如-lm</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">&lt; ,&gt;,! //operator</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">其他作为相对路径</font></font></li>
</ul>
</div>
</div>
<div id="outline-container-1_1_7" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_1_7"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.1.7</font></span><font style="font-weight: bold"> 总结 </font></font></font></h4>
<div id="text-1_1_7" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">gyp文档缺乏导致在分析这个系统的时候，也没有完全使用只是通过阅读文档来完成的，没有一个可以run的Makefile。 同时Makefile也想当难读(尽管如此，还是稍微看了一下生成的Makefile).最好可以结合chromium源代码来看看gyp是如何使用的(时间有限,我没有做).</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">gyp虽然是构建系统，并且通常来说构建文件倾向于使用描述性语言来完成，但是类json风格的描述性语言很容易形成过深的嵌套不利于阅读。 可以考虑使用其他方式描述性语言来完成。如果可以的话，结合过程语言也未尝不可。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">在运行时上gyp区分early和late phase两个阶段，同时允许通过target<sub style="position: static; line-height: 1.5; height: auto; top: auto">defaults这样一个section来设定全局属性。</sub>通过automatic variables这样的机制提供了反射功能，并且允许自定义操作，并且允许从外部shell中读取内容。 此外gyp允许提供跨模块之间的依赖管理(一个模块有如何这个模块被依赖的话，那么依赖这个模块的模块应该使用哪些属性).这些都是一个强大构建系统所必须的。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">从gyp层面就考虑了如何避免调用recursive make，通过规定某些属性内容只允许为路径名称并且允许include其他目录的.gpyi文件， 理论上可以生成不需要recurisve make的Makefile。同时在生成Makefile上面考虑了cross compile,out-of-source build问题。</font></font></p>
</div>
</div>
</div>
<div id="outline-container-1_2" class="outline-3">
<h3 style="border-bottom-style: dotted; border-bottom-color: #d6d6d6; line-height: 1.5; clear: none" id="sec-1_2"><font face="Verdana"><span class="section-number-3"><font style="font-size: 10pt"><font style="font-weight: bold">1.2</font></font></span><font style="font-size: 10pt"><font style="font-weight: bold"> Scons </font></font></font></h3>
<div id="text-1_2" class="outline-text-3">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">地址在</font></font><font style="font-size: 10pt"><a href="http://www.scons.org/"><font color="#0066ff"><font style="text-decoration: none" face="Verdana">http://www.scons.org/</font></font></a></font><font face="Verdana"><font style="font-size: 10pt">。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">总体来说算是一个比较成熟的产品，也发布过相当多的版本经过很长时间的演化。 这里是一些已经使用scons的项目列表</font></font><font style="font-size: 10pt"><a href="http://www.scons.org/wiki/SconsProjects"><font color="#0066ff"><font style="text-decoration: none" face="Verdana">http://www.scons.org/wiki/SconsProjects</font></font></a></font><font face="Verdana"><font style="font-size: 10pt">。 可以看到比较有名的两个就是MongnoDB和v8。</font></font></p>
</div>
<div id="outline-container-1_2_1" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_2_1"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.2.1</font></span><font style="font-weight: bold"> Make缺陷 </font></font></font></h4>
<div id="text-1_2_1" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">SCons对于Make缺陷也有一个总结，链接是</font></font><font style="font-size: 10pt"><a href="http://scons.org/wiki/FromMakeToScons"><font color="#0066ff"><font style="text-decoration: none" face="Verdana">http://scons.org/wiki/FromMakeToScons</font></font></a></font><font face="Verdana"><font style="font-size: 10pt">。 这里稍微总结一下，在设计Make代替品BuildSystem时候需要考虑到：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">make的命令是不可移植的，也就是说，对于*nix和win32必须单独编写不同的make命令。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make对于递归目录处理会牺牲速度。同时从目录角度来说，可能会发生重复检查的情况。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make语法十分ugly。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make使用环境变量，这样造成很多问题不可复现。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make对于一些检查过于简单，造成很多时候你必须make clean然后重新make。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make缺乏自动分析编译依赖。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make难以调试，主要是在规则冲突方面。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">客观地说除了3之外，其他都是非常严重的问题。对于3的话，要看你使用Makefile到什么程度了。 除了这些之外，如果按照Ninja的说法来说，Makefile还有一个速度过慢的缺点。</font></font></p>
</div>
</div>
<div id="outline-container-1_2_2" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_2_2"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.2.2</font></span><font style="font-weight: bold"> 构建文件 </font></font></font></h4>
<div id="text-1_2_2" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons的构建文件名称是统一的都称为SConstruct。当然为了方便目录的组织，也允许在各个目录下面存放SConscript， 然后最上面SConstruct收集这些SConscript组织成为一个大的构建文件。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">和gyp所不同的是，scons并没有生成一个所在平台的构建系统文件(linux-&gt;Makefile)，而是直接解释SConstruct来进行构建。 避开native build system文件的生成在一定程度上可以简化工作量，但是自己需要来完成整个构建活动。 同时速度可能会打一些折扣(比如现在google推出的ninja的构建系统构建系统很好，而scons就不能有效利用这个工具,而gyp只需要稍加改动就支持).个人观点来看的话，生成native build system文件可能是一个更好的选择。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">下面是一个简单例子</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">Program('main.cc')
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">然后使用方式是</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">[zhangyan@tc-cm-et18.tc.baidu.com test-scons]$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o main.o -c main.cc
g++ -o main main.o
scons: done building targets.
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">使用scons默认用来构建里面所有的内容。当然也可以使用scons &lt;target&gt;来构建某个或者是某些target。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons -c相当于make clean,scons -Q的话可以安静地构建，只是打印出真正执行的命令。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">如果是需要编译多个文件的话,可以使用python的列表格式。同时这些scons内置函数也是支持python的keyword argument这样的形式的：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">Program(target='hello',source=['main.cc','hello.cc'])
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">然后我们执行</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o main.o -c main.cc
g++ -o hello.o -c hello.cc
g++ -o hello main.o hello.o
scons: done building targets.
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">我们可以看到，在这个SConstruct这个Python Script里面Program等东西都实现成为了scons的内置函数， </font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">然后在表达上文件列表就是使用python列表形式。这样在一定层面上这就让用户接触到了[]这样的格式， 用户可能就会意识到当前可能是一个脚本，而不是以一种透明方式展现出来。不过通常来说,这样问题并不是很大， 用户也能够忍受列表以及keyword argument这样的东西，同时对于高级用户(熟悉python)的人也感到比较亲切。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">同时我们必须注意到，scons在构建目录下面存放了一个.sconsign.dblite这样一个文件。这个文件应该是 使用sqlite这样关系数据库的。因为scons很多特性需要依赖存储数据，比如cache隐式依赖，记录文件的md5等等信息， 单独使用一个辅助文件存放信息是一个不错的选择。</font></font></p>
</div>
</div>
<div id="outline-container-1_2_3" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_2_3"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.2.3</font></span><font style="font-weight: bold"> SConstruct文件剖析 </font></font></font></h4>
<div id="text-1_2_3" class="outline-text-4"></div>
<div id="outline-container-1_2_3_1" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_2_3_1"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.2.3.1</font></span><font style="font-weight: bold"> Builder </font></font></font></h5>
<div id="text-1_2_3_1" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">SConstruct主要支持的开发语言有C/C++以及Java。对于Java有专门的Builder，这里我们不谈.对于C/C++的Buidler有下面这几种：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Program //可执行程序</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">StaticLibrary //静态库</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">SharedLibrary //动态库</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">Object //目标文件</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">当然为了完备，还提供了一个万能的Buidler就是Command。对于Command来说的话，使用方式如下：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">Command('hello',['main.cc','hello.cc'],'g++ -o $TARGET $SOURCES')
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">撇开具体使用方法我们不说，对于自定义命令来说，我们最主要关心三个方面：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">target</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">dependencies</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">commands</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">在Command这个Builder很完整。同时为了方便还允许用户使用automatic variables，比如$TARGET和$SOURCES这两个变量， 类似于Makefile里面的$@和$</font><sup style="position: static; line-height: 1.5; bottom: auto; height: auto"><font style="font-size: 10pt">。关于Command讨论就到这里，接下来看看上面三个主要的Builder。</font></sup></font></p>
</div>
<div id="outline-container-1_2_3_1_1" class="outline-6">
<h6 style="line-height: 1.5; clear: none" id="sec-1_2_3_1_1"><font face="Verdana"><font color="#333333"><span class="section-number-6"><font style="font-weight: bold">1.2.3.1.1</font></span><font style="font-weight: bold"> 编译参数和自动分析编译依赖 </font></font></font></h6>
<div id="text-1_2_3_1_1" class="outline-text-6">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">默认情况下面如果这样写的话，那么是不能够制定任何编译参数的：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">Program('main.cc')
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">要不使用下一节方法一样构建一个环境，要不就需要显示地构造Object对象：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">obj=Object('main.cc',CCFLAGS='-DDEBUG')
Program('main',obj)
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">默认情况下面是不会自动分析编译依赖的，也就是说,如果main.h头文件发生变化的话，是不会发生重新构建的。 </font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">为了强制能够自动分析编译依赖，需要显示写明CPPPATH，就是include path：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">obj=Object('main.cc',CCFLAGS='-DDEBUG',CPPPATH=['.'])
Program('main',obj)
Decider('make')
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">Decider的意义是说按照时间戳更新的方式来检查，这个在检查依赖这节会提到。在做法上，</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">个人猜测scons也是使用g++ -MM -MG这样的方式来分析编译依赖。通常来说耗时会比较长。因为scons允许在调用参数中缓存上次编译依赖， 强制刷新编译依赖等，这样可以在耗时和功能上达到一个比较好的折衷。</font></font></p>
</div>
</div>
<div id="outline-container-1_2_3_1_2" class="outline-6">
<h6 style="line-height: 1.5; clear: none" id="sec-1_2_3_1_2"><font face="Verdana"><font color="#333333"><span class="section-number-6"><font style="font-weight: bold">1.2.3.1.2</font></span><font style="font-weight: bold"> 源文件使用不同参数编译 </font></font></font></h6>
<div id="text-1_2_3_1_2" class="outline-text-6">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">假设对于</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">env1=Environment(CCFLAGS='-DDEBUG')
env1.Program(target='debug_main',source=['main.cc'],)
env2=Environment()
env2.Program(target='release_main',source=['main.cc'])
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">关于Environment会在后面讲到，因为scons对于main.cc直接生成main.o这样文件，如果main.cc使用不同参数来进行编译的话如上，</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt"> 那么就可能出错。scons可以检测到对于同一个target使用不同参数编译，那么在执行时：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">[zhangyan@tc-cm-et18.tc.baidu.com test-scons]$ scons 
scons: Reading SConscript files ...

scons: *** Two environments with different actions were specified for the same target: main.o
File "/home/zhangyan/test-scons/SConstruct", line 4, in &lt;module&gt;
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">为了解决这个问题，可以使用Object这样的Builder来指定产生不同的文件名：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">env1=Environment(CCFLAGS='-DDEBUG')
obj1=env1.Object(target='debug_main',source=['main.cc'])
env1.Program(obj1)
env2=Environment()
obj2=env2.Object(target='release_main',source=['main.cc'])
env2.Program(obj2)
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">执行之后</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">[zhangyan@tc-cm-et18.tc.baidu.com test-scons]$ scons 
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o debug_main.o -c -DDEBUG main.cc
g++ -o debug_main debug_main.o
g++ -o release_main.o -c main.cc
g++ -o release_main release_main.o
scons: done building targets.
</font></pre>
</div>
</div>
<div id="outline-container-1_2_3_1_3" class="outline-6">
<h6 style="line-height: 1.5; clear: none" id="sec-1_2_3_1_3"><font face="Verdana"><font color="#333333"><span class="section-number-6"><font style="font-weight: bold">1.2.3.1.3</font></span><font style="font-weight: bold"> 库链接 </font></font></font></h6>
<div id="text-1_2_3_1_3" class="outline-text-6">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">可执行程序需要进行库链接，使用方式也是非常简单。Program这个Builder下面提供LIBPATH和LIBS这两个keyword arguments， 可以用来指定所需要链接的库。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">这样来写链接库首先是比较符合用户习惯的，但是这样会造成一个问题，这个在comake2中出现过，也是导致comake2并不提倡这个做法的原因， 那就是这样写的话不好构建依赖。假设下面两种写法：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">Program('main.cc',LIBS='./lib/libcm.a')
Program('main.cc',LIBS='cm',LIBPATH=['./lib'])
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">很明显第1中方式不仅仅写了所链接的库，scons本身还可以从中知道依赖什么文件，而comake2的做法就是希望用户显式依赖某个库。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">但是在scons中绕过了这个问题，是因为scons还有两个函数用来显示声明依赖的。对于显示声明依赖，个人看法是这个东西必须做为一个可选项， 对于小型程序显然用户希望构建系统自己生成依赖，而对于大型程序，显示声明依赖可以减少分析时间提高构建效率。</font></font></p>
</div>
</div>
</div>
<div id="outline-container-1_2_3_2" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_2_3_2"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.2.3.2</font></span><font style="font-weight: bold"> Dependencies </font></font></font></h5>
<div id="text-1_2_3_2" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">对于scons，除了在Builder里面提到的implicit dependencies这种隐式依赖，其他的依赖都必须显示说明的，或者是从指定的文件中进行分析。</font></font></p>
</div>
<div id="outline-container-1_2_3_2_1" class="outline-6">
<h6 style="line-height: 1.5; clear: none" id="sec-1_2_3_2_1"><font face="Verdana"><font color="#333333"><span class="section-number-6"><font style="font-weight: bold">1.2.3.2.1</font></span><font style="font-weight: bold"> 分析依赖 </font></font></font></h6>
<div id="text-1_2_3_2_1" class="outline-text-6">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">关于依赖共有两种类型，一种是普通的依赖就是A-&gt;B，另外一种是顺序依赖。顺序依赖的意思是说，其实A-&gt;B并不是真正构建A依赖于构建B。 只不过我们希望在构建顺序上，B在A构建之前。如果B发生变化，A不一定发生构建。这两种依赖分别对应于scons里面的Depends和Requires函数， 当然这个在Makefile里面也有方法表现出来。scons还提供一个函数ParseDepends可以分析g++ -MM -MG产生的.d文件，然后来判断依赖。</font></font></p>
</div>
</div>
<div id="outline-container-1_2_3_2_2" class="outline-6">
<h6 style="line-height: 1.5; clear: none" id="sec-1_2_3_2_2"><font face="Verdana"><font color="#333333"><span class="section-number-6"><font style="font-weight: bold">1.2.3.2.2</font></span><font style="font-weight: bold"> 判断依赖变化 </font></font></font></h6>
<div id="text-1_2_3_2_2" class="outline-text-6">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">判断依赖变化上，scons允许自己定义函数来判断文件是否发生变化。内置判断函数有下面几种：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Decider('make') //依赖对象修改时间是否比target修改时间大</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">Decider('timestamp-match') //依赖对象修改时间相对上次来说没有改变</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">Decider('MD5') //依赖对象内容的md5没有发生改变</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">或者是以上这些判断方式的组合</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">同样依赖变化还包括构建方式的参数变化，这点是值得学习的。实现起来也不是很难，可以在数据库中记录前一个构建某个target的输入文件以及构建参数，如果构建参数发生变化的话，那么重新构建并且在数据库中进行记录。</font></font></p>
</div>
</div>
</div>
<div id="outline-container-1_2_3_3" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_2_3_3"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.2.3.3</font></span><font style="font-weight: bold"> Environment </font></font></font></h5>
<div id="text-1_2_3_3" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">对于scons来说存在这么几个环境：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">External Environment //外部环境，可以通过import os获得</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">Construction Environment //创建环境，我们可以在SConstruct里面填写</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">Execution Environment //执行环境，scons在执行执行时所拥有的</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">和make有点不同的是，scons有意不将External Environment导入到Construction Environment里面来。 理由简单也非常合理，那就是如果一旦将环境变量也纳入scons的逻辑的话，那么构建过程是不可重复的。 可就是说，在某个人机器上搞得定但是另外一个机器上搞不定仅仅是因为环境变量不同。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">默认情况下面scons有一个默认的环境DefaultEnvironment()可以获得。然后我们可以在一个环境下面定义Builder等内容。 同时scons针对环境这个对象有相当多的操作，比如Clone,Repliace,Merge等。</font></font></p>
</div>
</div>
<div id="outline-container-1_2_3_4" class="outline-5">
<h5 style="line-height: 1.5; margin-bottom: 0px; clear: none" id="sec-1_2_3_4"><font face="Verdana"><font color="#333333"><span class="section-number-5"><font style="font-weight: bold">1.2.3.4</font></span><font style="font-weight: bold"> Hierarchical Builds </font></font></font></h5>
<div id="text-1_2_3_4" class="outline-text-5">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">层级目录之间的构建，在一开始也说过了，是通过导入其他目录下面的SConscript这样的文件来完成的， 最终也是在top-level directory上面发生构建。和gyp一样，SConscript也需要处理这样的问题， 就是定义哪些元素是file和directory,然后在解释的时候必须加上目录前缀。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">此外，相对于gyp,scons还引入了变量的export和import机制。某个SConscript可以export一部分变量出来， 然后另一个SConscript文件可以import这个变量进去。实现方式也非常简单，就是scons假设存在一个全局的变量池(variable pool),组织形式是一个字典。然后export就是写入这个字典，而import就是从这个字典导入内容。 跨文件之间的变量共享是非常必要的，这个在comake2里面共享编译依赖(已经做到),并且还有很强烈的需求就是共享编译参数(这点没有做到).</font></font></p>
</div>
</div>
</div>
<div id="outline-container-1_2_4" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_2_4"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.2.4</font></span><font style="font-weight: bold"> 其他问题 </font></font></font></h4>
<div id="text-1_2_4" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons提供了install方法，允许把某个文件安装到某个目录下面去，以相同或者是不同的名字安装。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons提供了平台无关的文件操作函数，比如copy,delete,rename,mkdir,touch等。这些函数做成为一个延迟函数对象.有一个Execute函数可以接受这些对象立即执行。其实关于这文件操作函数，个人认为可能完全没有必要，平台无关是非常好的概念， 但是对于文件系统实在是难于抽象出来。其他不说，首先考虑文件系统的名称就够费神半天，个人觉得把大部分细节屏蔽掉就ok。 对于需要平台相关操作,那就平台相关命令吧，scons对于命令操作也包装成了一个对象，这样可以延迟执行。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons支持out-of-source的编译方式，实现方式是通过copy源代码到另外一个地方然后进行编译，关于这么做的原因在下面地址也说了。 个人感觉，可能out-of-source的编译也不一定需要使用这种方式来完成(Android Build System就是out-of-source编译的,但是没有copy source).</font></font><a href="http://www.scons.org/doc/2.1.0.alpha.20101125/HTML/scons-user/c3348.html"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">http://www.scons.org/doc/2.1.0.alpha.20101125/HTML/scons-user/c3348.html</font></font></font></a></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons支持configure这样的功能，包括：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">检查头文件是否存在</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">检查库是否存在</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">检查typedef</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">检查函数是否存在</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">当然这只是配置中一部分。阅读了MongnoDB的SConstruct这个文件，发现其实还有相当多的检测是需要自己来完成的， 同时可能不希望按照scons内置的configure规则来进行检查。对于configure这样一个东西是非常需要，但是相当难做。GNU Autoconf个人感觉来说相对更加成熟一些，如果一定要做configure这样功能的话，可以首先参考一下GNU Autoconf.</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons还支持cache编译产出物这样的功能，不过个人还是觉得没有必要这么做，因为这样在scons内部实现了一个cache系统， 不仅仅加重了工作量，而且并没有做好，因为相对ccache来说，scons提供过于简单了。至于cache效率的话，是另外一个问题。 关于cache系统确实完全独立实现并且通用。</font></font></p>
</div>
</div>
<div id="outline-container-1_2_5" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_2_5"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.2.5</font></span><font style="font-weight: bold"> 总结 </font></font></font></h4>
<div id="text-1_2_5" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons是一个文档相对来说比较完整，已经被一些大型项目所使用的，比较成熟和完善的产品。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons本身使用Python Script来做描述文件，相对于gyp来说可读性会更好，表达功能上相对于gyp也更加强大， 但是容易造成一个问题就是速度会过慢，尤其对于scons这种执行方式。因为scons每次都是读取SConstruct/SConscript文件， 而不像gyp一样一次就生成Makefile，大部分时候是不需要变动Makefile，只是需要make的。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons对于编译依赖来说，提供了隐式分析和显示说明两种方式来描述依赖，然后针对隐式分析编译依赖也做了一些有效的优化。comake2在这点上也是提供了隐式分析和显示分析，但是却没有做一些优化，这样就造成每次生成Makefile时间过长。 如果是大型项目，耗时会非常长，在这些情况下面显示编写依赖可能会更好。对于依赖变化检测，也是提供了很多种方法。 并且如果构建参数发生变化，也是认为依赖发生变化，重新构建的。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons对于构建系统构建方式，和gyp一样认为构建必须从top-level开始进行。 和gyp一样，允许每个子目录下面存放SConscript描述文件，然后在上层最终收集上来。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">scons提供了环境这个概念，这点对于构建不同参数的版本作用非常大。并且scons对于环境这个概念引入也非常自然， 直接env.Program(..)和没有使用环境的Program(..)在编写内容上相差无几，同时也提供了很多关于环境的操作，并且提供一个默认环境。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">和其他构建系统一样，scons还提供了平台无关文件操作，install方法，out-of-source编译，configure，以及编译产物的cache， 不过个人看来其实每个部分要不就做得相当粗糙(out-of-source编译,configure)，要不就是鸡肋(文件操作，编译产物cache，install)， 当然也可能是因为自己对于scons了解不够深入引起的。</font></font></p>
</div>
</div>
</div>
<div id="outline-container-1_3" class="outline-3">
<h3 style="border-bottom-style: dotted; border-bottom-color: #d6d6d6; line-height: 1.5; clear: none" id="sec-1_3"><font face="Verdana"><span class="section-number-3"><font style="font-size: 10pt"><font style="font-weight: bold">1.3</font></font></span><font style="font-size: 10pt"><font style="font-weight: bold"> Ninja </font></font></font></h3>
<div id="text-1_3" class="outline-text-3">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">地址在</font></font><font style="font-size: 10pt"><a href="https://github.com/martine/ninja/blob/master/manual.asciidoc"><font color="#0066ff"><font style="text-decoration: none" face="Verdana">https://github.com/martine/ninja/blob/master/manual.asciidoc</font></font></a></font><font face="Verdana"><font style="font-size: 10pt">。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">ninja是也是为了加速Chromium的编译(gyp也是，不过gyp提供的是一个前端，而ninja是实际描述文件。 现在已经有一个patch for gyp来生成ninja文件了)。定位非常清晰，就是达到更快的构建速度。对比的对象是没有任何递归的Makefile。 作者给出了一个实测数据,30000个文件，make使用10seconds才开始进行构建，ninja只用了1s中就开始进行构建了。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">ninja的设计是对于make的缺陷的考虑，认为make有下面几点造成编译速度过慢：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">隐式规则，make包含很多默认推导规则。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">变量计算，比如编译参数应该如何计算出来。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">依赖对象计算。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">ninja认为描述文件应该是这样的：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">依赖必须显式写明(为了方便可以产生依赖描述文件)</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">没有任何变量计算</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">没有默认规则，没有任何默认值</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">针对这点所以基本上可以认为ninja就是make的最最精简版。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">但是ninja相对于make增加了下面这些功能，可以看到都非常有用，并且这些在上层是不能够完成的，只有在这层做：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">如果构建命令发生变化，那么这个构建也会重新执行。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">所依赖的目录在构建之前都已经创建了，因为如果不是这样的话，我们执行命令之前都要去生成目录。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">每条构建规则，除了执行命令之外，还允许有一个描述，真正执行打印这个描述而不是实际执行命令。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">每条规则的输出都是buffered的，也就是说并行编译，输出内容不会被搅和在一起。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">ninja也支持order dependencies，还有一系列辅助工具比如查询某个target的依赖以及构建规则，打印出整个构建图等功能。 关于ninja文档里面没有提到如何判断依赖变化，但是如果目的是提高速度的话选用方式应该还是时间戳(学习scons之后,考虑一下时间戳的匹配可能会更快)。</font></font></p>
</div>
</div>
<div id="outline-container-1_4" class="outline-3">
<h3 style="border-bottom-style: dotted; border-bottom-color: #d6d6d6; line-height: 1.5; clear: none" id="sec-1_4"><font face="Verdana"><span class="section-number-3"><font style="font-size: 10pt"><font style="font-weight: bold">1.4</font></font></span><font style="font-size: 10pt"><font style="font-weight: bold"> ABS </font></font></font></h3>
<div id="text-1_4" class="outline-text-3">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">ABS(Android Build System).关于这个BuildSystem的文档可以在android的源代码的build/core/build-system.html里面找到。ABS是虽然是使用make的，但是做了相当多的规范。首先看看ABS所规定的原则和策略有哪些：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">支持多平台目标</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">使用non-recursive make</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">支持环境和配置的设置</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">out-of-source的编译方式</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">依赖能够自动分析出来</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">隐藏执行命令输出</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许使用GLOB语法来包含文件</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许在一个directory里面编译多个targets</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许每个目录有各自描述文件</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">希望以后支持下面这些特性：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">对于不同的平台可以同时编译</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">如果头文件删除,那么依赖可以检测到</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">能够自动进行所有平台构建</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">之前做过关于ABS的编译优化，稍微看过一下ABS是如何组织的。大致组织方式是在：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">在top-level包含Makefile。内容很简单，就是include build/core/main.mk。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">在build/core/main.mk里面include了每个目录下面的.mk文件。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">然后在build/core下面系统一系列的辅助.mk文件，比如executable.mk(编译可执行程序)，均被包含到main.mk里面。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">对于在每个子目录下面的Android.mk文件里面，只需要负责设置一些变量。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">然后在make时候，子目录变量收集起来，配合辅助.mk文件，生成一系列规则。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">然后进行构建。</font></font></li>
</ul>
</div>
</div>
<div id="outline-container-1_5" class="outline-3">
<h3 style="border-bottom-style: dotted; border-bottom-color: #d6d6d6; line-height: 1.5; clear: none" id="sec-1_5"><font face="Verdana"><span class="section-number-3"><font style="font-size: 10pt"><font style="font-weight: bold">1.5</font></font></span><font style="font-size: 10pt"><font style="font-weight: bold"> CMake </font></font></font></h3>
<div id="text-1_5" class="outline-text-3">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">下面是CMake的有用链接：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">CMake主页，</font></font><a href="http://www.cmake.org/"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">http://www.cmake.org/</font></font></font></a></li>
<li><font face="Verdana"><font style="font-size: 10pt">为什么KDE会从SCons切换到CMak，.</font></font><a href="http://lwn.net/Articles/188693/"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">http://lwn.net/Articles/188693/</font></font></font></a></li>
<li><font face="Verdana"><font style="font-size: 10pt">台湾人写的CMake overview.ppt风格不错，</font></font><a href="http://wenku.baidu.com/view/e27778db6f1aff00bed51e60.html"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">http://wenku.baidu.com/view/e27778db6f1aff00bed51e60.html</font></font></font></a></li>
<li><font face="Verdana"><font style="font-size: 10pt">CMake-behind scenes of code development，</font></font><a href="http://wenku.baidu.com/view/c1dbc3eb998fcc22bcd10dff.html"><font face="Verdana"><font style="font-size: 10pt" color="#0066ff"><font style="text-decoration: none">http://wenku.baidu.com/view/c1dbc3eb998fcc22bcd10dff.html</font></font></font></a></li>
<li><font face="Verdana"><font style="font-size: 10pt">cmake –help-html cmake-help.html，可以查看CMake的内置HTML帮助页，难读但是更像是一个Specification。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">cmake的全称是cross-platform makefile generator，但是猜想后来后端很多但是名字保留下来了。 现在的定位应该是cross-platform build system generator，通过读取源代码目录下面的CMakeLists.txt文件， 然后进行configure同时生成native build system所需要的构建文件。在Unix下面主要生成：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">unix makefile.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">code blocks - unix makefile.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">eclipse cdt4 - unix makefile.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">kdevelop3 - unix makefile.</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">cmake相对于其他构建工具优越的几点有：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">C/C++的头文件自动分析</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">生成Makefile进行make时候比较漂亮，能够显示编译进度</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">生成Makefile的target比较丰富</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">cmake可以配合其他工具进行无缝集成，比如CTest/CDash</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">KDE/OepnCV已经使用了CMake，对于质量比较有保证</font></font></li>
</ul>
</div>
<div id="outline-container-1_5_1" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_1"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.1</font></span><font style="font-weight: bold"> 构建文件 </font></font></font></h4>
<div id="text-1_5_1" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">编写一个简单的CMakeLists.txt非常简单：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">project(main)
add_executable(main main.cc)
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">然后进行configure并且同时生成Makefile：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">[zhangyan@tc-cm-et18.tc.baidu.com test-cmake]$ cmake .
-- The C compiler identification is GNU
-- The CXX compiler identification is GNU
-- Check for working C compiler: /home/zhangyan/utils/bin/gcc
-- Check for working C compiler: /home/zhangyan/utils/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/zhangyan/test-cmake
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">输入参数指定source位置，这样来进行out-of-source的构建。cmake在第一次分析CMakeLists.txt的时候，</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt"> 会对环境进行分析然后将一系列得到的环境内容保存在CMakeCache.txt文件里面，得到一系列的变量，相当于配置的选项。 然后外部允许通过自己指定来改写这些默认得到的环境，但是这个环境依然不能够被source所使用，比较好地可以被程序使用的方式， 就是像GNU Build System一样生成的config.h。关于如何生成config.h，会在特定的节里面提到。</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">[zhangyan@tc-cm-et18.tc.baidu.com test-cmake]$ make
[100%] Building CXX object CMakeFiles/main.dir/main.cc.o
Linking CXX executable main
[100%] Built target main
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">cmake本身也提供了类似于gyp的功能,将编译依赖输出graphviz的图,方便查看.</font></font></p>
</div>
</div>
<div id="outline-container-1_5_2" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_2"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.2</font></span><font style="font-weight: bold"> CMakeLists.txt解析 </font></font></font></h4>
<div id="text-1_5_2" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">cmake里面提供的描述语言，内置了函数，宏，条件判断，流程控制，同时还有变量(不清楚是否有嵌套作用域)， 还有一些简单的数据结构比如整数字符串以及列表，相当的完整。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">关于CMake有相当多的语法和属性，这里就不一一讲解，只是谈谈相对于其他构件系统比较独特的地方。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">add<sub style="position: static; line-height: 1.5; height: auto; top: auto">custom</sub><sub style="position: static; line-height: 1.5; height: auto; top: auto">command允许用户进行自定义的命，通过指定output</sub>,input,command，同时允许指定这些命令在：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">dependencies构建之前执行</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">dependencies构建之后，但是target构建之前执行</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">target构建之后执行</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">add</font><sub style="position: static; line-height: 1.5; height: auto; top: auto"><font style="font-size: 10pt">test允许全局环境增加test用例，允许自己使用test的启动命令。</font></sub></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">build</font><sub style="position: static; line-height: 1.5; height: auto; top: auto"><font style="font-size: 10pt">command能够获得某个target的构建命令。</font></sub></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">file定义了一系列文件操作方法，为多平台的文件操作提供了抽象。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">find提供了一系列查找文件，库，package，program的方法，简化配置的生成。 对于find</font><sub style="position: static; line-height: 1.5; height: auto; top: auto"><font style="font-size: 10pt">package内置很多检测库的方法，并且有大量的内置变量可以被使用。</font></sub></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">set<sub style="position: static; line-height: 1.5; height: auto; top: auto">property</sub>/get</font><sub style="position: static; line-height: 1.5; height: auto; top: auto"><font style="font-size: 10pt">property设置和获取属性。</font></sub></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">include包含另外一个文件进来，语义和Make的include是一样的。而add<sub style="position: static; line-height: 1.5; height: auto; top: auto">subdirectory添加一个子目录，对应的Makefile就是</sub>"make -C …"。 从效果上说，cmake并没有提供类似于gyp和scons的import功能来方便进行项目的整体构建，还是将一个个目录单独进行构建。</font></font></p>
</div>
</div>
<div id="outline-container-1_5_3" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_3"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.3</font></span><font style="font-weight: bold"> 变量和属性 </font></font></font></h4>
<div id="text-1_5_3" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">变量和属性其实是一个概念，我们使用$&lt;…&gt;来进行变量引用，而使用set来设置变量。对于里面的内容，语法如下：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">OPTION:target
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">引用target下面的某个OPTION。这些就可以针对每个target来进行一些参数定制了。比如：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">SET(cppflags:libecho.a,"-DDEBUG -W -Wall")
</font></pre>
</div>
</div>
<div id="outline-container-1_5_4" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_4"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.4</font></span><font style="font-weight: bold"> 注释 </font></font></font></h4>
<div id="text-1_5_4" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">注释也作为属性存在于target或者是全局环境中.对于target的注释来说，在进行build的时候，cmake能够让注释在执行命令之前就显示出来。 这样一方面可以利于开发者来进行调试，同时产生的输出信息对于用户也更加友好。</font></font></p>
</div>
</div>
<div id="outline-container-1_5_5" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_5"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.5</font></span><font style="font-weight: bold"> 编译类型 </font></font></font></h4>
<div id="text-1_5_5" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">cmake的编译类型一共分为4类，可以简化编译选项的设置：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Debug //调试版本</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">Release //发布版本</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">RelWithDebInfo //发布版本但是带上调试信息</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">MinSizeRel //发布版本但是简化二进制大小</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">可以通过-DCMAKE<sub style="position: static; line-height: 1.5; height: auto; top: auto">BUULD</sub><sub style="position: static; line-height: 1.5; height: auto; top: auto">TYPE</sub>=…在命令行里面指定.使用一个编译类型会配置上一系列的编译选项，用户可以在内部继续修改这些选项。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">写到这里，关于选项这种东西，有一些想法。在设计选项方面，我们必须考虑下面这几个功能：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">选项必须进行分配，然后可以进行批量开启。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许用户在描述文件中覆盖和增加选项。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许用户在命令行也指定这些选项。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">这样在易用，功能方面能够达到比较好的折衷。</font></font></p>
</div>
</div>
<div id="outline-container-1_5_6" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_6"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.6</font></span><font style="font-weight: bold"> 生成config.h </font></font></font></h4>
<div id="text-1_5_6" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">cmake生成config.h的方法也是套用模板的方式。里面提供了一个函数，可以将类似于：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="src src-Python"><font style="font-size: 10pt" color="#333333">#define JPEG_FOUND %{jpeg_found_value}d
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">然后在cmake运行时环境里面存在jpeg<sub style="position: static; line-height: 1.5; height: auto; top: auto">found</sub><sub style="position: static; line-height: 1.5; height: auto; top: auto">value这样变量进行替换，然后生成config</sub>.h。 非常不错的idea(猜想GNU Build System应该也是这样完成的).</font></font></p>
</div>
</div>
<div id="outline-container-1_5_7" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_7"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.7</font></span><font style="font-weight: bold"> Makefile </font></font></font></h4>
<div id="text-1_5_7" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">生成的Makefile，包含下面这样几个大的target：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">make //默认构建</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make &lt;target&gt; //构建某个target</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make clean //删除中间构建结果</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make depend //重新计算依赖</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">make &lt;source&gt;.ii / &lt;source&gt;.s // &lt;source&gt;.o //生成中间文件</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">cmake能够自动分析C/C++的编译依赖。同时如果CMakeLists.txt发生变化的话，那么也会重新生成Makefile。 因为时间有限，对于生成的Makefile也没有仔细分析。</font></font></p>
</div>
</div>
<div id="outline-container-1_5_8" class="outline-4">
<h4 style="line-height: 1.5; clear: none" id="sec-1_5_8"><font face="Verdana"><font color="#333333"><span class="section-number-4"><font style="font-weight: bold">1.5.8</font></span><font style="font-weight: bold"> 总结 </font></font></font></h4>
<div id="text-1_5_8" class="outline-text-4">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">是一个相当成熟的项目，并且有一系列的外围和cmake形成一个整体，内置了相当多的辅助函数来帮助使用其他开源的库， 所以在设计和实用性上可以看得出来是相当严肃的。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">因为语法是自己定义的语言，所以学习起来有一定的成本。在描述能力上来说还是不错的， 但是缺乏一些高级的数据结构比如字典可能会造成某些情况下面使用比较麻烦。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">同时cmake还提供一系列检测环境的能力，然后通过生成config.h来进行source file configuration。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">最后生成的Makefile在构建时候，用户友好方面不错。并且在CMakeLists.txt变化以及源文件依赖的.h文件变化的话，cmake会重新生成Makefile并且进行编译的。不过因为时间有限也没有对Makefile进行仔细的分析。</font></font></p>
</div>
</div>
</div>
<div id="outline-container-1_6" class="outline-3">
<h3 style="border-bottom-style: dotted; border-bottom-color: #d6d6d6; line-height: 1.5; clear: none" id="sec-1_6"><font face="Verdana"><span class="section-number-3"><font style="font-size: 10pt"><font style="font-weight: bold">1.6</font></font></span><font style="font-size: 10pt"><font style="font-weight: bold"> Others </font></font></font></h3>
<div id="text-1_6" class="outline-text-3">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">关于BuildSystem一些有用的链接，在这里给出：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Build Management Entry</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://www.dmoz.org/Computers/Software/Build_Management/"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://www.dmoz.org/Computers/Software/Build_Management/</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">这个是关于一个构建管理项目的入口，里面有很多解决构建项目遇到问题的工具和方案。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Make Alternatives</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://freshmeat.net/articles/make-alternatives"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://freshmeat.net/articles/make-alternatives</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">Make的代替品。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">A.A.P</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://www.a-a-p.org/tools_build.html"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://www.a-a-p.org/tools_build.html</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">这是VIM作者编写的一个构建系统框架，是一个可以扩展的系统。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Boost.Build</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://www.boost.org/doc/tools/build/index.html"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://www.boost.org/doc/tools/build/index.html</font></font></font></a><font style="font-size: 10pt"><a href="http://www.boost.org/boost-build2/index.html"><font color="#0066ff"><font style="text-decoration: none" face="Verdana">http://www.boost.org/boost-build2/index.html</font></font></a></font><font face="Verdana"><font style="font-size: 10pt">Boost使用的BuildSystem，也是旨在解决C++跨平台构建问题。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Makeit</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://www.dscpl.com.au/projects/makeit/"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://www.dscpl.com.au/projects/makeit/</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">时间限制，没有仔细研究。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Waf</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://code.google.com/p/waf/"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://code.google.com/p/waf/</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">基本上可以认为是和SCons的一个sibling，似乎SCons和Waf都是从某个项目分支出来的。 语法上都采用了Python Script解决方案，但是Waf看上去似乎没有SCons简单。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">SDS</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://sds.sourceforge.net/index.html"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://sds.sourceforge.net/index.html</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">时间限制，没有仔细研究。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">MSBuild</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://msdn.microsoft.com/zh-cn/library/dd393574.aspx"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://msdn.microsoft.com/zh-cn/library/dd393574.aspx</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">M$的构建系统，时间限制没有仔细研究，并且对于Windows下面的开发环境也不是很熟悉。 唯一了解就是MSBuild也使用XML来进行描述。</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">Maven</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><a href="http://maven.apache.org/"><font color="#0066ff"><font style="text-decoration: none" face="Verdana"><font style="font-size: 10pt">http://maven.apache.org/</font></font></font></a><font face="Verdana"><font style="font-size: 10pt">Java项目开发最常使用的构建系统工具之一。Maven描述方法是使用XML来描述，虽然也可以描述一些过程化的内容， 但是感觉就是没有Python Script简洁和清晰。Maven相对于之前这些构建系统，有下面几点重大改进的地方：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">规范项目目录结构</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">引入Maven Source Code Repository概念</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">规范目录结构使得大家开发Maven很容易，而Maven Source Code Repository使得协作开发非常简单， 只要配置好Source Code Repo，然后Maven能够自动下载编译所需要的依赖模块并且进行编译，能够很好地进行多模块之间的持续集成开发。</font></font></p>
</div>
</div>
<div id="outline-container-1_7" class="outline-3">
<h3 style="border-bottom-style: dotted; border-bottom-color: #d6d6d6; line-height: 1.5; clear: none" id="sec-1_7"><font face="Verdana"><span class="section-number-3"><font style="font-size: 10pt"><font style="font-weight: bold">1.7</font></font></span><font style="font-size: 10pt"><font style="font-weight: bold"> 个人感觉 </font></font></font></h3>
<div id="text-1_7" class="outline-text-3">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">关于构建系统，个人感觉这里是一个大坑，想要满足所有人的要求是非常困难的。对于构建系统，我们希望有下面这些点(一部分是我觉得应该这样做)：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">构建文件表达能力够强，使用Python Script，可以借鉴SCons这样的语法。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">生成native build system文件，一方面可以提高速度，另外一方面可以简化工作量如cmake。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">提供丰富变量，包括编译时和运行时。只有提供了这些变量，才能够提供更加灵活的功能如cmake。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许跨文件之间的export和import，比如使用gyp这样的方式而不是使用scons这样的方法(比较笨拙)。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">如果是生成Makefile，避开生成递归的Makefile，比如scons和gyp所提倡的，而cmake似乎没有这样做。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许out-of-source编译，并且避开scons这样的copy整个源代码的实现方式如cmake。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">允许自动分析编译依赖，并且是在make的时候自动分析，而不是在生成Makefile就写死如cmake。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">支持检测编译选项的改变，如果编译选项改变自动发生构建如ninja和scons.</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">支持多种检测文件变化方式如scons。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">如果有定位为跨平台的构建系统的话，需要提供平台无关的文件操作，但是个人觉得会费神。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">提供configure的功能吗，像cmake一样提供很多内置的configure功能，但允许scons一样定制。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">还有很多其他的点，一时总结的不是很完全，以后有空会继续补充(TODO)。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">考虑到BuildSystem是一个相当大的坑，其实我们完全没有必要自己去完成一个构建系统，最坏情况下面使用Makefile或者是ninja就OK了。 对于baidu面临最大的问题，就是需要提供一种类似于maven的source coderepository机制，允许下载和编译所需要的依赖， 同时可以从source code中知道这个模块的依赖来满足基于主干的开发。而在底层构建的话，选用SCons或者是CMake都没有太大问题。</font></font></p>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">如果仅仅考虑上面这个问题，我们完全可以这样做：</font></font></p>
<ul style="list-style-type: disc; margin-left: 45px">
<li><font face="Verdana"><font style="font-size: 10pt">对于每个模块的最外层，提供一个COMAKE文件</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">COMAKE文件里面只是写明CONFIGS这样的东西。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">然后comake2 -U &amp; comake2 -B可以帮助用户下载和搭建环境。</font></font></li>
<li><font face="Verdana"><font style="font-size: 10pt">comake2能够生成一份构建系统辅助文件。</font></font></li>
</ul>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">比如我们需要使用public/ub的话,我们在COMAKE里面写好</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">WORKROOT('http://www.cnblogs.com/../')
CONFIGS('public/ub')
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">然后生成的COMAKE.mk如下</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">PUBLIC_UB_PATH="http://www.cnblogs.com/../public/ub"
PUBLIC_UB_INCLUDE_CFLAGS="-Ihttp://www.cnblogs.com/../public/ub/output/include"
PUBLIC_UB_INCLUDE_CXXFLAGS="-Ihttp://www.cnblogs.com/../public/ub/output/include"
PUBLIC_UB_LIBS="http://www.cnblogs.com/../public/ub/output/lib/libub.a"
</font></pre>
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px"><font face="Verdana"><font style="font-size: 10pt">然后在用户自己的Makefile里面通过include来使用这些变量：</font></font></p>
<pre style="padding-bottom: 0px; line-height: 1.5; background-color: transparent; padding-left: 0px; padding-right: 0px; margin-bottom: 0px; padding-top: 0px" class="example"><font style="font-size: 10pt" color="#333333">include "COMAKE.mk"
</font></pre>
</div>
</div>
</div>
<div style="line-height: 1.5" id="postamble">
<p style="margin-top: 5px; text-indent: 0px; margin-bottom: 5px" class="author"><font face="Verdana"><font style="font-size: 10pt">Author: zhangyan04@baidu.com</font></font></p>
</div>
 
 										                        <div class="loc_link"><ul><li>本文固定链接: <a href="http://www.wy182000.com/2011/09/01/buildsystem/" rel="bookmark" title="BuildSystem">http://www.wy182000.com/2011/09/01/buildsystem/</a></li>
                        <li>转载请注明: <a href="http://www.wy182000.com/author/wy182000/" title="由wy182000发布" rel="author">wy182000</a> <time>2011年09月01日 </time>于 <a href="http://www.wy182000.com/" title="访问Studio">Studio</a> 发表</li></ul>
                        </div>
                        						                        <div class="author_info">
                        	<div class="au_top_bar"><div class="edit_date">最后编辑：<time>2011-09-01</time></div><b>作者：wy182000</b></div>
                            <div class="avatar"><img alt='' src='http://0.gravatar.com/avatar/4fbf31e160a0b7edc99cf5bf9ec531b5?s=96&amp;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&amp;r=G' class='avatar avatar-96 photo' height='96' width='96' /></div>
                            <div class="type_out"><span class="ttxx">这个作者貌似有点懒，什么都没有留下。</span><div class="au_links"><a href="http://www.wy182000.com?author=1" class="c1"><i class="icon-home"></i> 站内专栏</a></div></div>
                        <div class="cls"></div>
                        </div>
                        					</article>
                    
                    <!-- .entry-content -->

					<!-- .entry-utility -->
				</div><!-- #post-## -->
<div class="c-bot">
    <aside class="cb_bq"><i class="icon-tag icon-large"></i> <a href="http://www.wy182000.com/tag/gyp/" rel="tag">gyp</a>，<a href="http://www.wy182000.com/tag/scons/" rel="tag">scons</a></aside>        <div class="cls"></div>
    </div>
    <br />
				<div id="nav-below" class="navigation">
					<div class="nav-previous"><a href="http://www.wy182000.com/2011/09/09/gcc%e8%af%a6%e8%a7%a3/" rel="next"><span class="meta-nav"><i class="icon-arrow-left"></i></span> gcc详解 </a></div>
					<div class="nav-next"><a href="http://www.wy182000.com/2011/08/16/linux-%e8%ae%be%e7%bd%ae-%e5%a4%9aip%ef%bc%8c%e5%a4%9avlan/" rel="prev">Linux 设置 多ip，多vlan  <i class="icon-arrow-right"></i></a></div>
				</div><!-- #nav-below -->
<div class="cls"></div>
				                    <div class="ad_2">
						                    </div>
                                <div class="relatedposts">
<h3 class="widget-title"><i class="icon-warning-sign"></i> 您可能还会对这些文章感兴趣！</h3>
<ul>
		<li><a href="http://www.wy182000.com/2009/02/17/xna-sidebar-trigonometry/" rel="bookmark" title="详细阅读 XNA Sidebar - Trigonometry">XNA Sidebar - Trigonometry</a></li>
		<li><a href="http://www.wy182000.com/2009/02/22/attenuation-and-doppler-pitch-shifting-overview/" rel="bookmark" title="详细阅读 Attenuation and Doppler Pitch Shifting Overview">Attenuation and Doppler Pitch Shifting Overview</a></li>
		<li><a href="http://www.wy182000.com/2013/04/24/sedawk%e7%ac%94%e8%ae%b0%e4%b9%8bsed%e7%af%87/" rel="bookmark" title="详细阅读 Sed&amp;awk笔记之sed篇">Sed&amp;awk笔记之sed篇</a></li>
		<li><a href="http://www.wy182000.com/2011/10/18/rpm%e5%8c%85-%e7%94%9f%e6%88%90%e5%b7%a5%e5%85%b7-rpmbuild/" rel="bookmark" title="详细阅读 rpm包 生成工具 rpmbuild">rpm包 生成工具 rpmbuild</a></li>
		<li><a href="http://www.wy182000.com/2009/02/23/%e9%9f%b3%e6%95%88/" rel="bookmark" title="详细阅读 音效">音效</a></li>
		<li><a href="http://www.wy182000.com/2013/03/28/git%e8%af%a6%e8%a7%a3%e4%b9%8b%e4%ba%94-%e5%88%86%e5%b8%83%e5%bc%8fgit/" rel="bookmark" title="详细阅读 Git详解之五 分布式Git">Git详解之五 分布式Git</a></li>
		<li><a href="http://www.wy182000.com/2013/03/28/git%e8%af%a6%e8%a7%a3%e4%b9%8b%e4%b9%9d-git%e5%86%85%e9%83%a8%e5%8e%9f%e7%90%86/" rel="bookmark" title="详细阅读 Git详解之九 Git内部原理">Git详解之九 Git内部原理</a></li>
		<li><a href="http://www.wy182000.com/2009/02/19/xact-unknown-error-code/" rel="bookmark" title="详细阅读 XACT unknown error code">XACT unknown error code</a></li>
	</ul>
<div class="cls"></div>
</div>

<div id="comments">
								<div id="respond" class="comment-respond">
				<h3 id="reply-title" class="comment-reply-title">留下一个回复 <small><a rel="nofollow" id="cancel-comment-reply-link" href="/2011/09/01/buildsystem/#respond" style="display:none;">取消回复</a></small></h3>
									<p class="must-log-in">你必须先 <a href="http://www.wy182000.com/wordpress/wp-login.php?redirect_to=http%3A%2F%2Fwww.wy182000.com%2F2011%2F09%2F01%2Fbuildsystem%2F">登录</a>才能发表评论。</p>												</div><!-- #respond -->
			</div><!-- #comments -->
      </div><!-- #content -->
  </div><!-- #container -->
<script type="text/javascript">loading('55%',1000)</script>
    <aside id="primary" class="side" role="complementary">
        <ul class="xoxo">
<li id="text-4" class="widget-container widget_text"><h3 class="widget-title">Note :</h3>			<div class="textwidget"><p>今天被公安局约见了，说评论有违法信息没有屏蔽，警官人还不错，建议关掉评论功能。<br />
以后不再提供评论功能，有问题请发邮件联系。</p>
</div>
		</li><li id="categories-5" class="widget-container widget_categories"><h3 class="widget-title">分类目录</h3><select name='cat' id='cat' class='postform' >
	<option value='-1'>选择分类目录</option>
	<option class="level-0" value="16">Computer&nbsp;&nbsp;(213)</option>
	<option class="level-1" value="3">&nbsp;&nbsp;&nbsp;.net&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="4">&nbsp;&nbsp;&nbsp;AI&nbsp;&nbsp;(4)</option>
	<option class="level-1" value="5">&nbsp;&nbsp;&nbsp;ASM&nbsp;&nbsp;(2)</option>
	<option class="level-1" value="117">&nbsp;&nbsp;&nbsp;build&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="139">&nbsp;&nbsp;&nbsp;c++&nbsp;&nbsp;(8)</option>
	<option class="level-1" value="92">&nbsp;&nbsp;&nbsp;Chromium&nbsp;&nbsp;(2)</option>
	<option class="level-1" value="246">&nbsp;&nbsp;&nbsp;cocos2d-x&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="89">&nbsp;&nbsp;&nbsp;Compiler&nbsp;&nbsp;(3)</option>
	<option class="level-1" value="134">&nbsp;&nbsp;&nbsp;game&nbsp;&nbsp;(4)</option>
	<option class="level-1" value="120">&nbsp;&nbsp;&nbsp;gcc&nbsp;&nbsp;(2)</option>
	<option class="level-1" value="6">&nbsp;&nbsp;&nbsp;GDB&nbsp;&nbsp;(2)</option>
	<option class="level-1" value="7">&nbsp;&nbsp;&nbsp;ghs&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="153">&nbsp;&nbsp;&nbsp;git&nbsp;&nbsp;(13)</option>
	<option class="level-1" value="84">&nbsp;&nbsp;&nbsp;GNU&nbsp;&nbsp;(2)</option>
	<option class="level-1" value="8">&nbsp;&nbsp;&nbsp;Hardware&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="141">&nbsp;&nbsp;&nbsp;jni&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="9">&nbsp;&nbsp;&nbsp;Linux&nbsp;&nbsp;(55)</option>
	<option class="level-1" value="170">&nbsp;&nbsp;&nbsp;lua&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="129">&nbsp;&nbsp;&nbsp;math&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="142">&nbsp;&nbsp;&nbsp;mysql&nbsp;&nbsp;(5)</option>
	<option class="level-1" value="183">&nbsp;&nbsp;&nbsp;network&nbsp;&nbsp;(13)</option>
	<option class="level-1" value="106">&nbsp;&nbsp;&nbsp;nosql&nbsp;&nbsp;(4)</option>
	<option class="level-1" value="10">&nbsp;&nbsp;&nbsp;other&nbsp;&nbsp;(3)</option>
	<option class="level-1" value="145">&nbsp;&nbsp;&nbsp;physics&nbsp;&nbsp;(2)</option>
	<option class="level-1" value="11">&nbsp;&nbsp;&nbsp;Prodeus&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="78">&nbsp;&nbsp;&nbsp;tcp/ip&nbsp;&nbsp;(4)</option>
	<option class="level-1" value="12">&nbsp;&nbsp;&nbsp;UI&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="82">&nbsp;&nbsp;&nbsp;Windows&nbsp;&nbsp;(4)</option>
	<option class="level-1" value="13">&nbsp;&nbsp;&nbsp;X Window&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="14">&nbsp;&nbsp;&nbsp;XACT&nbsp;&nbsp;(7)</option>
	<option class="level-1" value="15">&nbsp;&nbsp;&nbsp;XNA&nbsp;&nbsp;(76)</option>
	<option class="level-0" value="219">Lijia&nbsp;&nbsp;(12)</option>
	<option class="level-1" value="220">&nbsp;&nbsp;&nbsp;Linux&nbsp;&nbsp;(11)</option>
	<option class="level-1" value="230">&nbsp;&nbsp;&nbsp;Web&nbsp;&nbsp;(1)</option>
	<option class="level-0" value="95">Music&nbsp;&nbsp;(1)</option>
	<option class="level-0" value="20">Personal&nbsp;&nbsp;(48)</option>
	<option class="level-1" value="19">&nbsp;&nbsp;&nbsp;Blog&nbsp;&nbsp;(5)</option>
	<option class="level-1" value="189">&nbsp;&nbsp;&nbsp;cocos2d-x&nbsp;&nbsp;(14)</option>
	<option class="level-1" value="182">&nbsp;&nbsp;&nbsp;Common&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="21">&nbsp;&nbsp;&nbsp;Game&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="243">&nbsp;&nbsp;&nbsp;git&nbsp;&nbsp;(3)</option>
	<option class="level-1" value="147">&nbsp;&nbsp;&nbsp;life&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="72">&nbsp;&nbsp;&nbsp;Linux&nbsp;&nbsp;(14)</option>
	<option class="level-1" value="264">&nbsp;&nbsp;&nbsp;Unity&nbsp;&nbsp;(3)</option>
	<option class="level-1" value="214">&nbsp;&nbsp;&nbsp;WIndows&nbsp;&nbsp;(1)</option>
	<option class="level-1" value="172">&nbsp;&nbsp;&nbsp;Work&nbsp;&nbsp;(3)</option>
	<option class="level-1" value="238">&nbsp;&nbsp;&nbsp;xcode&nbsp;&nbsp;(2)</option>
	<option class="level-1" value="174">&nbsp;&nbsp;&nbsp;随笔&nbsp;&nbsp;(2)</option>
</select>

<script type='text/javascript'>
/* <![CDATA[ */
	var dropdown = document.getElementById("cat");
	function onCatChange() {
		if ( dropdown.options[dropdown.selectedIndex].value > 0 ) {
			location.href = "http://www.wy182000.com/?cat="+dropdown.options[dropdown.selectedIndex].value;
		}
	}
	dropdown.onchange = onCatChange;
/* ]]> */
</script>

</li><li id="tag_cloud-5" class="widget-container widget_tag_cloud"><h3 class="widget-title">标签</h3><div class="tagcloud"><a href='http://www.wy182000.com/tag/linux-2/' class='tag-link-66' title='35个话题' style='font-size: 14px;'>linux (35)</a> 
<a href='http://www.wy182000.com/tag/git/' class='tag-link-153' title='17个话题' style='font-size: 14px;'>git (17)</a> 
<a href='http://www.wy182000.com/tag/cocos2d-x/' class='tag-link-189' title='15个话题' style='font-size: 14px;'>cocos2d-x (15)</a> 
<a href='http://www.wy182000.com/tag/zeromq/' class='tag-link-185' title='12个话题' style='font-size: 14px;'>ZeroMQ (12)</a> 
<a href='http://www.wy182000.com/tag/zmq/' class='tag-link-187' title='10个话题' style='font-size: 14px;'>ZMQ (10)</a> 
<a href='http://www.wy182000.com/tag/centos/' class='tag-link-161' title='8个话题' style='font-size: 14px;'>centos (8)</a> 
<a href='http://www.wy182000.com/tag/android/' class='tag-link-234' title='7个话题' style='font-size: 14px;'>android (7)</a> 
<a href='http://www.wy182000.com/tag/c/' class='tag-link-139' title='6个话题' style='font-size: 14px;'>c++ (6)</a> 
<a href='http://www.wy182000.com/tag/vpn/' class='tag-link-178' title='5个话题' style='font-size: 14px;'>vpn (5)</a> 
<a href='http://www.wy182000.com/tag/ios/' class='tag-link-236' title='4个话题' style='font-size: 14px;'>ios (4)</a> 
<a href='http://www.wy182000.com/tag/nosql/' class='tag-link-106' title='4个话题' style='font-size: 14px;'>nosql (4)</a> 
<a href='http://www.wy182000.com/tag/iptables/' class='tag-link-111' title='4个话题' style='font-size: 14px;'>iptables (4)</a> 
<a href='http://www.wy182000.com/tag/bison/' class='tag-link-87' title='4个话题' style='font-size: 14px;'>bison (4)</a> 
<a href='http://www.wy182000.com/tag/http/' class='tag-link-179' title='4个话题' style='font-size: 14px;'>http (4)</a> 
<a href='http://www.wy182000.com/tag/mysql/' class='tag-link-142' title='4个话题' style='font-size: 14px;'>mysql (4)</a> 
<a href='http://www.wy182000.com/tag/godaddy/' class='tag-link-48' title='4个话题' style='font-size: 14px;'>godaddy (4)</a> 
<a href='http://www.wy182000.com/tag/windows-2/' class='tag-link-83' title='4个话题' style='font-size: 14px;'>windows (4)</a> 
<a href='http://www.wy182000.com/tag/vim/' class='tag-link-73' title='4个话题' style='font-size: 14px;'>vim (4)</a> 
<a href='http://www.wy182000.com/tag/game-2/' class='tag-link-41' title='4个话题' style='font-size: 14px;'>game (4)</a> 
<a href='http://www.wy182000.com/tag/blog-2/' class='tag-link-44' title='4个话题' style='font-size: 14px;'>blog (4)</a> 
<a href='http://www.wy182000.com/tag/udp/' class='tag-link-79' title='4个话题' style='font-size: 14px;'>udp (4)</a> 
<a href='http://www.wy182000.com/tag/apache/' class='tag-link-49' title='4个话题' style='font-size: 14px;'>apache (4)</a> 
<a href='http://www.wy182000.com/tag/wordpress/' class='tag-link-45' title='3个话题' style='font-size: 14px;'>wordpress (3)</a> 
<a href='http://www.wy182000.com/tag/tc/' class='tag-link-165' title='3个话题' style='font-size: 14px;'>tc (3)</a> 
<a href='http://www.wy182000.com/tag/amqp/' class='tag-link-184' title='3个话题' style='font-size: 14px;'>AMQP (3)</a> 
<a href='http://www.wy182000.com/tag/system/' class='tag-link-211' title='3个话题' style='font-size: 14px;'>system (3)</a> 
<a href='http://www.wy182000.com/tag/mac/' class='tag-link-235' title='3个话题' style='font-size: 14px;'>mac (3)</a> 
<a href='http://www.wy182000.com/tag/nginx/' class='tag-link-254' title='3个话题' style='font-size: 14px;'>nginx (3)</a> 
<a href='http://www.wy182000.com/tag/php/' class='tag-link-50' title='3个话题' style='font-size: 14px;'>php (3)</a> 
<a href='http://www.wy182000.com/tag/xcode/' class='tag-link-238' title='3个话题' style='font-size: 14px;'>xcode (3)</a> 
<a href='http://www.wy182000.com/tag/sed/' class='tag-link-88' title='3个话题' style='font-size: 14px;'>sed (3)</a> 
<a href='http://www.wy182000.com/tag/tcpip/' class='tag-link-78' title='3个话题' style='font-size: 14px;'>tcp/ip (3)</a> 
<a href='http://www.wy182000.com/tag/kvm/' class='tag-link-151' title='3个话题' style='font-size: 14px;'>kvm (3)</a> 
<a href='http://www.wy182000.com/tag/cron/' class='tag-link-69' title='3个话题' style='font-size: 14px;'>cron (3)</a> 
<a href='http://www.wy182000.com/tag/flex/' class='tag-link-90' title='3个话题' style='font-size: 14px;'>flex (3)</a> 
<a href='http://www.wy182000.com/tag/physics/' class='tag-link-145' title='3个话题' style='font-size: 14px;'>physics (3)</a> 
<a href='http://www.wy182000.com/tag/proxy/' class='tag-link-108' title='3个话题' style='font-size: 14px;'>proxy (3)</a> 
<a href='http://www.wy182000.com/tag/yacc/' class='tag-link-86' title='2个话题' style='font-size: 14px;'>yacc (2)</a> 
<a href='http://www.wy182000.com/tag/google/' class='tag-link-94' title='2个话题' style='font-size: 14px;'>google (2)</a> 
<a href='http://www.wy182000.com/tag/dump/' class='tag-link-99' title='2个话题' style='font-size: 14px;'>dump (2)</a> 
<a href='http://www.wy182000.com/tag/gdb-2/' class='tag-link-80' title='2个话题' style='font-size: 14px;'>gdb (2)</a> 
<a href='http://www.wy182000.com/tag/lex/' class='tag-link-85' title='2个话题' style='font-size: 14px;'>lex (2)</a> 
<a href='http://www.wy182000.com/tag/vfs/' class='tag-link-76' title='2个话题' style='font-size: 14px;'>vfs (2)</a> 
<a href='http://www.wy182000.com/tag/fork/' class='tag-link-81' title='2个话题' style='font-size: 14px;'>fork (2)</a> 
<a href='http://www.wy182000.com/tag/gnu/' class='tag-link-84' title='2个话题' style='font-size: 14px;'>GNU (2)</a> </div>
</li>		<li id="recent-posts-3" class="widget-container widget_recent_entries">		<h3 class="widget-title">近期文章</h3>		<ul>
					<li>
				<a href="http://www.wy182000.com/2014/12/12/linux-%e8%99%9a%e6%8b%9f%e6%9c%ba%e5%8a%a8%e6%80%81%e5%a2%9e%e5%8a%a0lvm%e5%88%86%e5%8c%ba%e5%a4%a7%e5%b0%8f/">Linux 虚拟机动态增加lvm分区大小</a>
							<span class="post-date">2014/12/12</span>
						</li>
					<li>
				<a href="http://www.wy182000.com/2014/11/16/%e5%b0%8f%e7%b1%b3%e8%b7%af%e7%94%b1-vpn%e5%8a%a0chnroutes-%e5%ae%9e%e7%8e%b0/">小米路由 vpn加chnroutes 实现</a>
							<span class="post-date">2014/11/16</span>
						</li>
					<li>
				<a href="http://www.wy182000.com/2014/10/16/unity-%e8%84%9a%e6%9c%acattributes/">unity 脚本Attributes</a>
							<span class="post-date">2014/10/16</span>
						</li>
					<li>
				<a href="http://www.wy182000.com/2014/10/10/disunity%e8%a7%a3%e5%8c%85unity%e8%b5%84%e6%ba%90/">disunity解包unity资源</a>
							<span class="post-date">2014/10/10</span>
						</li>
					<li>
				<a href="http://www.wy182000.com/2014/10/10/windows%e6%89%b9%e5%a4%84%e7%90%86%e6%96%87%e4%bb%b6/">Windows批处理文件</a>
							<span class="post-date">2014/10/10</span>
						</li>
				</ul>
		</li><li id="catpostswidget-4" class="widget-container widget_random_posts"><h3 class="widget-title">随机文章</h3><ul><li><a href="http://www.wy182000.com/2011/07/25/nosql%e6%95%b0%e6%8d%ae%e5%ba%93%e7%ac%94%e8%b0%88/" title="阅读 NoSQL数据库笔谈 详细内容">NoSQL数据库笔谈</a></li><li><a href="http://www.wy182000.com/2013/03/27/git-%e5%88%86%e6%94%af%e7%ae%a1%e7%90%86%e7%ad%96%e7%95%a5/" title="阅读 Git 分支管理策略 详细内容">Git 分支管理策略</a></li><li><a href="http://www.wy182000.com/2013/04/17/linux-%e6%b5%81%e9%87%8f%e6%8e%a7%e5%88%b6%e5%ae%9e%e6%96%bd%e6%8c%87%e5%8d%97/" title="阅读 Linux 流量控制实施指南 详细内容">Linux 流量控制实施指南</a></li><li><a href="http://www.wy182000.com/2013/11/07/linux%e6%9c%8d%e5%8a%a1%e5%99%a8%e5%ae%89%e8%a3%85/" title="阅读 Linux服务器安装 详细内容">Linux服务器安装</a></li><li><a href="http://www.wy182000.com/2011/08/05/iptables-%e6%8c%87%e5%8d%97/" title="阅读 Iptables 指南 详细内容">Iptables 指南</a></li></ul></li><li id="linkcat-16" class="widget-container widget_links"><h3 class="widget-title">Computer</h3>
	<ul class='xoxo blogroll'>
<li><a href="https://github.com/wy182000">github</a></li>
<li><a href="http://blog.codingnow.com/" target="_blank">云风blog</a></li>
<li><a href="http://www.xuanyusong.com/" target="_blank">雨松MOMO</a></li>
<li><a href="http://linux.vbird.org/" target="_blank">鳥哥的 Linux 私房菜</a></li>

	</ul>
</li>
        </ul>
    </aside><!-- #primary .widget-area -->

<script type="text/javascript">loading('78%',1000)</script>
<div class="cls"></div>
</section><!-- #main -->
<div class="cls"></div>
	<footer id="footer" role="contentinfo">
		<div id="colophon">

<div id="site-info">
<a href="javascript:void(0)" onClick="goRoll(0)" id="goTop">返回顶部</a>
<a href="http://www.wy182000.com/sitemap.xml">网站地图</a>&nbsp;
<a href="http://www.miitbeian.gov.cn/" rel="external nofollow" target="_blank">沪ICP备13010764号-1| 沪公网备3101090592432943-1</a>
<script type="text/javascript">
var _bdhmProtocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cscript src='" + _bdhmProtocol + "hm.baidu.com/h.js%3F13f2d2510d7d00af08150072689c18ef' type='text/javascript'%3E%3C/script%3E"));
</script>@wy182000&nbsp;| Theme <span id='official'>frontopen2</span></div>
		</div>	</footer></div><script type='text/javascript' src='http://www.wy182000.com/wordpress/wp-includes/js/comment-reply.min.js?ver=3.9.3'></script>
<div id="float"><a id="float_gotop" class="floatbtn"  href="javascript:void()" onClick="goRoll(0)" title="返回顶部"></a><a class="linbak floatbtn" href="http://www.wy182000.com/wordpress/wp-admin/" title="登陆&注册"></a><a id="float_goend" class="floatbtn" href="javascript:void()" onClick="goend()" title="转到底部"></a></div>
</body>
</html><script type="text/javascript">loading('100%',1000)</script>
